<script setup lang="ts">
  import routeComponentName from '@/config/route-component-name'
  import {
    ElForm,
    ElFormItem,
    ElInput,
    ElSelect,
    ElOption,
    ElRadioGroup,
    ElRadio,
    ElUpload,
    ElIcon,
    UploadRawFile,
    UploadFile,
    ElImageViewer,
    FormInstance,
  } from 'element-plus'
  import {
    useEnterpriseNoticeCreate,
    useGetEnterpriseNoticeDetail,
  } from '@/services/pages/enterprise-notice/useEnterpriseNotice'
  import { Upload } from '@element-plus/icons-vue'
  import Editor from '@/components/business/editor/Editor.vue'
  import { computed, onMounted, onUnmounted, ref } from 'vue'
  import { useTagsViewStore } from '@/store/modules/tagsView'
  import { useRoute, useRouter } from 'vue-router'
  import { HMessage, HMessageBox } from '@/components/common/message'
  import { deleteFile, fileUpload } from '@/api/upload'

  const { form, createLoading, create, resetForm } = useEnterpriseNoticeCreate()
  const { detail, getDetailLoading, getDetail } = useGetEnterpriseNoticeDetail()

  defineOptions({
    name: routeComponentName.enterpriseNotice.enterpriseNoticeCreate,
  })

  // 标签状态管理
  const tagsViewStore = useTagsViewStore()

  // 图片预览组件显示状态
  const imgPreviewVisible = ref(false)

  // 表单校验规则
  const formRules = {
    name: [{ required: true, message: '请输入公告名称', trigger: ['change', 'blur'] }],
    visibilityType: [{ required: true, message: '请选择可见类型', trigger: ['change', 'blur'] }],
    status: [{ required: true, message: '请选择状态', trigger: ['change', 'blur'] }],
    topUp: [{ required: true, message: '请选择是否置顶', trigger: ['change', 'blur'] }],
  }

  // 表单组件实例
  const formInstance = ref<FormInstance | null>(null)

  // 编辑器组件实例
  const editorInstance = ref<InstanceType<typeof Editor> | null>(null)

  // 激活路由对象
  const route = useRoute()

  // 全局路由对象
  const router = useRouter()

  // 文件上传加载
  const fileUploadLoading = ref(false)

  // 文件删除加载
  const fileDelLoading = ref(false)

  // 封面文件对象
  const coverFileObj = ref<{ file: UploadRawFile; url: string; fileName: string }>({
    file: null,
    url: '',
    fileName: '',
  })

  // 文件删除路径集合
  const fileDelUrls = ref<Array<string>>([])

  // 加载
  const loading = computed(() => {
    return (
      createLoading.value ||
      fileUploadLoading.value ||
      fileDelLoading.value ||
      getDetailLoading.value
    )
  })

  /**
   * 封面更新事件
   */
  const handleUploadCover = (file: UploadFile) => {
    coverFileObj.value = {
      file: file.raw,
      url: URL.createObjectURL(file.raw),
      fileName: file.raw.name,
    }
  }

  /**
   * 删除企业公告
   */
  const onDelCover = () => {
    // 不含blob就说明是服务器的图片，可以删除
    if (!coverFileObj.value.url.includes('blob')) {
      fileDelUrls.value.push(coverFileObj.value.url)
    }
    coverFileObj.value = {
      file: null,
      url: '',
      fileName: '',
    }
    form.value.coverImage = ''
  }

  /**
   * 封面预览事件
   */
  const onPreview = () => {
    imgPreviewVisible.value = true
  }

  /**
   * 取消事件
   */
  const onCancel = () => {
    resetForm()
    tagsViewStore.delView(route.path)
    router.push('/enterprise/notice/list')
  }

  /**
   * 封面上传
   */
  const coverUpload = async () => {
    if (coverFileObj.value.file) {
      fileUploadLoading.value = true
      const res = await fileUpload([coverFileObj.value.file])
      form.value.coverImage = res.data.data.rows[0]
      fileUploadLoading.value = false
    }
  }

  /**
   * 内容的文件上传
   */
  const contentFileUpload = async () => {
    const files = editorInstance.value.getUploadFiles()
    if (files.length > 0) {
      fileUploadLoading.value = true
      const fileUploadRes = await fileUpload(files.map((item) => item.file))
      files.forEach((file, index) => {
        editorInstance.value.convertTempPathToServerPath(
          file.tempUrl,
          fileUploadRes.data.data.rows[index],
        )
      })
      fileUploadLoading.value = false
    }
  }

  /**
   * 内容的文件删除
   */
  const contentFileDel = async () => {
    const deletedFiles = editorInstance.value.getDeletedFiles()
    if (deletedFiles.length > 0) {
      fileDelLoading.value = true
      await deleteFile(deletedFiles)
      fileDelLoading.value = false
    }
  }

  /**
   * 封面删除
   */
  const coverDel = async () => {
    if (fileDelUrls.value.length > 0) {
      fileDelLoading.value = true
      await deleteFile(fileDelUrls.value)
      fileDelLoading.value = false
    }
  }

  /**
   * 提交事件
   */
  const onSubmit = async () => {
    if (formInstance.value && editorInstance.value) {
      try {
        await formInstance.value.validate()
        await coverUpload()
        await contentFileUpload()
        await contentFileDel()
        await coverDel()
        form.value.content = await editorInstance.value.getEditorValue()
        const res = await create()
        if (res.code === 20000) {
          HMessage.success('创建成功')
          resetForm()
          tagsViewStore.delView(route.path)
          router.push({ path: '/enterprise/notice/list', query: { isUpdate: 1 } })
          return
        }
        HMessageBox.error(res.message)
      } catch (error) {
        // error
      }
    }
  }

  /**
   * 获取公告详情
   */
  const getNoticeDetail = async () => {
    if (route.params.id) {
      await getDetail(route.params.id as string)
      form.value = { ...detail.value }
      coverFileObj.value.url = detail.value.coverImage
      coverFileObj.value.fileName = detail.value.coverImage.split('/').at(-1).split('.')[0]
    }
  }

  onMounted(() => {
    if (editorInstance.value) {
      editorInstance.value.mountEditor()
    }

    getNoticeDetail()
  })

  onUnmounted(() => {
    if (editorInstance.value) {
      editorInstance.value.destoryEditor()
    }
  })
</script>

<template>
  <div v-loading="loading" class="enterprise-notice-create-wrapper">
    <div class="enterprise-notice-create">
      <div class="header">
        <div class="title">创建企业公告</div>
        <div class="btn-group">
          <h-plain-button @click="onSubmit">提交</h-plain-button>
          <h-button @click="onCancel">取消</h-button>
        </div>
      </div>
      <div class="divider"></div>
      <el-form ref="formInstance" :model="form" :rules="formRules" inline-message>
        <el-form-item label="公告名称" prop="name">
          <el-input v-model.trim="form.name" placeholder="请输入公告名称" maxlength="20" />
        </el-form-item>
        <el-form-item label="可见类型" prop="visibilityType">
          <el-select v-model="form.visibilityType" placeholder="请选择可见类型">
            <el-option :value="1" label="全部可见"></el-option>
            <el-option :value="2" label="部门可见"></el-option>
            <el-option :value="3" label="公司可见"></el-option>
          </el-select>
        </el-form-item>
        <el-form-item label="是否置顶" prop="topUp">
          <el-radio-group v-model="form.topUp">
            <el-radio :value="true">是</el-radio>
            <el-radio :value="false">否</el-radio>
          </el-radio-group>
        </el-form-item>
        <el-form-item label="状态" prop="status">
          <el-radio-group v-model="form.status">
            <el-radio :value="false">启用</el-radio>
            <el-radio :value="true">禁用</el-radio>
          </el-radio-group>
        </el-form-item>
        <el-form-item label="公告封面">
          <el-upload
            v-if="!coverFileObj.url"
            :auto-upload="false"
            :show-file-list="false"
            class="cover"
            accept="image/*"
            :on-change="handleUploadCover"
          >
            <el-icon color="#333">
              <Upload />
            </el-icon>
            <div class="txt">添加封面</div>
          </el-upload>
          <div v-else class="img-wrapper">
            <h-tooltip-text
              :text="coverFileObj.fileName"
              :max-width="100"
              :height="28"
            ></h-tooltip-text>
            <h-link :height="28" @click="onPreview">预览</h-link>
            <h-link :height="28" type="error" @click="onDelCover">删除</h-link>
          </div>
        </el-form-item>
      </el-form>
      <div class="editor-wrapper">
        <editor
          ref="editorInstance"
          :del-function="[
            'strike',
            'code',
            'subscript',
            'superscript',
            'eraser',
            'todo',
            'emoji',
            'link',
            'table',
          ]"
          :value="form.content"
        ></editor>
      </div>
    </div>

    <el-image-viewer
      v-if="imgPreviewVisible"
      :url-list="[coverFileObj.url]"
      @close="imgPreviewVisible = false"
    ></el-image-viewer>
  </div>
</template>

<style scoped lang="scss">
  .enterprise-notice-create-wrapper {
    padding: 12px;
    box-sizing: border-box;
    height: calc(100vh - 92px);

    .enterprise-notice-create {
      width: 100%;
      height: 100%;
      background-color: #fff;
      padding: 12px;
      box-sizing: border-box;
      display: flex;
      flex-direction: column;

      .header {
        display: flex;
        justify-content: space-between;
        padding: 0 12px;

        .title {
          font-size: 14px;
          font-weight: bold;
        }

        .btn-group {
          display: flex;
          column-gap: 5px;
        }
      }

      .divider {
        margin: 12px 0;
        border-bottom: 1px dotted #d4d4d4;
      }

      :deep(.el-form) {
        display: flex;
        column-gap: 36px;
        padding: 0 12px;

        .el-form-item {
          .el-form-item__label {
            height: 28px;
            line-height: 28px;
          }

          .el-form-item__content {
            align-items: flex-start;
            max-width: 200px;

            .el-input {
              width: 200px;
            }

            .el-select {
              width: 100px;
            }

            .el-radio-group {
              column-gap: 6px;
              flex-direction: row;
              flex-wrap: nowrap;

              .el-radio {
                margin: 0;
                height: 28px;
                column-gap: 1px;

                .el-radio__label {
                  padding: 0;
                  height: 28px;
                  line-height: 28px;
                }
              }
            }

            .cover {
              width: 100px;
              height: 28px;
              display: flex;
              justify-content: center;
              align-items: center;
              box-shadow: 0 0 0 1px #dcdfe6 inset;

              .el-upload {
                height: 28px;
                column-gap: 5px;

                .txt {
                  color: #333;
                  height: 28px;
                  line-height: 28px;
                }
              }
            }

            .img-wrapper {
              display: flex;
              column-gap: 10px;
            }

            .el-form-item__error {
              padding: 0;
              margin: 3px 0 0 0;
            }
          }
        }
      }

      .editor-wrapper {
        flex: 1;
        padding: 12px;
        height: 0;

        :deep(.aie-container-main) {
          flex: 1;
          height: 0 !important;
          overflow: auto;
        }
      }
    }
  }
</style>
